/**
 * @class : zookeeper调用
 * Created by CJF on 2017/11/14
 */

const zookeeper = require('node-zookeeper-client'),
  EventEmitter = require('events').EventEmitter,
  errCode = require('../../conf/errorCode'),
  {zkOpt} = require('../../conf'),
  http = require('../helper/http'),
  util = require('../helper/util'),
  wrap = require('../helper/wrap'),
  client = zookeeper.createClient(zkOpt.hosts, {
    sessionTimeout: 30000,
    spinDelay: 1000,
    retries: 0,
  });

let connected = false,
  zks = {};
client.addAuthInfo('digest', new Buffer(zkOpt.auth));
client.once('connected', function() {
  for (let key in zks) {
    zks[key]._getData();
  }
  connected = true;
});

client.on('state', function(state) {
  if (state === 'disconnected') {
    client.connect();
  }
});
client.connect();

/**
 * Create a new ZK object for the given zookeeper node.
 * 
 * @param {string} opt
 * @public
 */

class ZK extends EventEmitter {
  constructor(opt) {
    super();
    this.nodePath = opt;
    //增加观测path
    if (!zks[opt]) {
      zks[opt] = this;
    }
    if (connected) {
      this._getData();
    }
  }
  _getData() {
    client.getData(
      this.nodePath,
      event => {
        this._getData();
      },
      (error, _data, stat) => {
        if (error || !_data) {
          return this.emit(
            'update',
            util.genCode(
              errCode.GET_ZOOKEEPER_NODE,
              errCode.GET_ZOOKEEPER_NODE,
            ),
            null,
          );
        }
        let appId = _data.toString().match(/.+?appId=(\d+)/)[1],
          hostname = zkOpt.hostname,
          pathNQs = zkOpt.pathNQs.replace('${appId}', appId),
          validations = {
            hostname,
            pathNQs,
            apiNo: errCode.GET_BIZWORK_USER_INFO,
          };
        http.get(validations, (err, _rel) => {
          if (err) {
            this.emit(
              'update',
              util.genCode(errCode.GET_BIZCONF, errCode.GET_BIZCONF),
              null,
            );
          } else {
            _rel = wrap.changeData(
              _rel,
              wrap.names.onlinePro,
              wrap.names.front,
              wrap.names.end,
            );
            this.emit('update', null, _rel);
          }
        });
      },
    );
  }
}

exports.ZK = ZK;
